
var	imgOpenSrc = "images/minus_tree.gif" ;
var	imgCloseSrc = "images/plus_tree.gif" ;
var	imgLeafSrc  = "images/solid_tree.gif" ;
function initTOCFrame ()
{
	//create the TOCTree (the constructor will save a ref to the obj in window.TheTOCTree)

	var tree = new REGTree( window, top.frames.DUMP );
	tree.m_bSyncTOCWithContent = false ;
	tree.m_hiColor = "black";
	tree.m_hiBGColor = "#FFE3B7";
	tree.m_bHiliteCurLink = true ;
	if ( isIE )
	{
		tree.m_basePath = "";
	}
	tree.m_imgOpenSrc  = imgOpenSrc ;
	tree.m_imgCloseSrc = imgCloseSrc ;
	tree.m_imgLeafSrc  = imgLeafSrc ;
	// various magic numbers for Nav4
	if ( isNav4 )
	{
		tree.m_nYOffset = 10 ;		// the Y pos for the first TOC link - we have to absolutly position it in Nav4
		// in Nav4 we can't read a folder's className attribute so we have to infer its level in the
		// hierarchy by comparing its "left" attribute to the following:
		tree.m_nIndentDelta = 14 ;	// no. of pixels each class is indented - should match stylesheet
		tree.m_nXOffset = 10;		// no. of pixels root level folder is indented - should match stylesheet
		var div = getElem( "THEHILITE" );
		if ( div )
		{
		   div.visibility = "hidden" ;
		}
	}
	tree.initialize();
	// check for a starting path stored in the top window
	var folderId = 0;
	if ( top.curPath() && (null != pathMap[ top.curPath() ]) )
	{
		folderId = pathMap[ top.curPath() ];
		tree.tf( folderId );
		tree.si( folderId );
	}
	// hook up the DUMP frame's click event
	//addEvent( top.frames.DUMP.document, "click", 
	  //	onDumpWinClick, true, "Event.CLICK" );
	top.frames.DUMP.TheTOCTree = TheTOCTree;
	// set title to folder's registry path on mouseover

}	// onLoad ()
function onDumpWinClick ( e )
{
	return TheTOCTree.onDocClick( e ? e : top.frames.DUMP.event );
}	// 
/*
	registry data functions
*/

function _enumPropArray ( a, callback, maxDepth, fNoPath, fListsOnly, fDepthLast )
{
	if ( ! ( a && callback ) ) return ;
	// default maxDepth is zero, i.e. full recursion
	if ( _enumPropArray.arguments.length < 3 ) maxDepth = 0 ;
	function _enumProps( a, curDepth, curPath )
	{
		var newPath = "";
		if ( maxDepth && ( curDepth >= maxDepth ) ) return ;
		if ( fDepthLast )	// loop through the list, call the callback but don't recurse
		{
			for ( var x in a )
			{

				if ( fNoPath )
				{
					newPath = "";
				}
				else
				{	
					if ( ! curPath )
						newPath = x.toString();
					else if ( "/" == curPath.charAt( curPath.length - 1 ) )
						newPath = curPath + x.toString();
					else
						newPath = curPath + "." + x.toString();
				}
				// if callback returns a non-zero value that's a signal to abort the enumeration
			    if( callback( a, x, curDepth, newPath ) )
			    	return ;
			}
		}
		for ( var x in a )
		{

			if ( ! fNoPath )
			{	
				// add the current subprop to the path...
				curPath += (curPath ? "." : "") + x.toString();
			}
			// if callback returns a non-zero value that's a signal to abort the enumeration
			if ( ! fDepthLast ) // already called callback above
			{
		    	if ( callback( a, x, curDepth, fNoPath ? null : curPath ) )
				{
		    		return ;
				}
			}
			if ( isObj( a[ x ] ) )
			{
				curDepth++ ;
				_enumProps( a[ x ], curDepth, curPath ) 
				curDepth-- ;
				if ( ! fNoPath )
				{
					// ...and then remove current subprop from the path...
					curPath = curDepth ? curPath.leftProp( -1 ) : "" ;
				}
			}
			else if ( fListsOnly || fDepthLast ) //assume array is sorted so that all lists are grouped at the beginning
			{
				break ;
			}
		}
	}
	_enumProps( a, 0, "" );
}
function sortCaseInsensitive ( a, b )
{
	if (a == null) return -1;
	if (b == null) return 1;
	if( (parseInt(a) == a) && 
	    (parseInt(b) == b) )
	{
	 	return ( parseInt(a) < parseInt(b) ? -1 : 1 );
	}
	else if( (typeof(a) == "number") && 
	    	 (typeof(b) == "number") )
	{
	 	return ( a < b ? -1 : 1 );
	}
	else
	{
		return ( a.toString().toLowerCase() < b.toString().toLowerCase() ? -1 : 1 );
	}
}
// sorts the array into something useful
// lists first, variables next
// alphabetical within each group
function _sortArray ( a, level )
{
	var a2 = new Array();
	var aVars = new Array();
	var aLists = new Array();
	for ( var prop in a )
	{
		if ( isObj( a[ prop ] ) )
		{
			aLists[ aLists.length ] = prop ;
		}
		else
		{
			aVars[ aVars.length ] = prop ;
		}
	}
	if ( isNav4 )
	{
		// nav4 crashes when given a sort func
		aLists.sort();
		aVars.sort();
	}
	else
	{
		aLists.sort( sortCaseInsensitive );
		aVars.sort( sortCaseInsensitive );
	}
	for ( var i = 0; i < aLists.length; i++ )
	{

		a2[ aLists[ i ] ] = _sortArray( a[ aLists[ i ] ], level + 1 );
	}
	for ( i = 0; i < aVars.length; i++ )
	{
		a2[ aVars[ i ] ] = a[ aVars[ i ] ];
	}
	return a2 ;
}
regData = new Array();
function hasChildFolder ( a )
{
	var hasChildren = false ;
	function _lookAhead ( a2, prop2 )
	{
		if ( isObj( a2[ prop2 ] ) )
		{
			hasChildren = true ;
			return 1 ;
		}
	}
	_enumPropArray( a, _lookAhead, 1, true, true );
	return hasChildren;
}
var linkMap = new Array();
var pathMap = new Array();
var IDToPathMap = new Array();
function updateIndexes ( aRef, path, divID )
{
	linkMap[ divID ] = aRef ;
	pathMap[ path ] = divID  ;
	IDToPathMap[ divID ] = path;
}	// updateIndexes
function writeTOC ()
{
	var divID = 0 ;
	var classAttrStart = ' class="l' ;
	var divTagStart = '<DIV id="z' ; // can't use a number or '_' to begin layer id
	var imgTagStart = '<IMG BORDER=0 SRC="' ;
	var toggleLinkTagStart = '<A href="javascript://" onclick="TheTOCTree.tf(' ;
	var showLinkTagStart   = '<A HREF="javascript://" onclick="TheTOCTree.si(' ;
	var divTagEnd = '</A></DIV>' ;
	function _TOCcallback ( a, prop, curDepth, path )
	{
		if ( isObj( a[ prop ] ) )
		{
			var classAttr = classAttrStart + curDepth + '"' ;
			var divNameAttr = divTagStart + divID + '"' ;
			var imgTag ;
			if ( hasChildFolder( a[ prop ] ) )
				imgTag= toggleLinkTagStart + divID + ');">' + imgTagStart + imgCloseSrc + '"></A>' ;
			else
				imgTag= "<A>" + imgTagStart + imgLeafSrc + '"></A>' ;
			// save reference to server data
			updateIndexes( a[ prop ], path, divID );
			document.write( divNameAttr + classAttr + '>' + imgTag + showLinkTagStart + divID + ')">' + prop.toString().ent() + divTagEnd );

			divID++ ;
		}
		return false;
	}
	//var root = location.hostname ;
	if ( (!top.curPath()) || (top.curPath() == "REG_ROOT") )
	{
		//regData[ root ] = _sortArray( d, 0 );

		regData = _sortArray( d, 0 );

	}
	else
	{
		// create/initialize an array hierarchy that leads to the
		// desired subtree
		var tempA = top.curPath().split( "." );
		var evalStr = "";
		//var pathStr = "regData['" + root + "']";
		var pathStr = "regData";
		for ( var i = 0; i < tempA.length; i++ )
		{
			evalStr += pathStr + "['" + tempA[ i ] + "']=[];\n";
			pathStr += "['" + tempA[ i ] + "']";
		}
		evalStr += pathStr + "=_sortArray( d, 0 );\n";
		//regData[ root ] = [];
		eval( evalStr );
	}
	delete d ;
	_enumPropArray( regData, _TOCcallback, 0, false, true );
}	// writeTOC
var lastSearchHitPath = "" ;
function searchData ( target, searchType, fNext, fRegEx )
{
	if ( ! fNext )
	{
		lastSearchHitPath = "" ;
	}
	else
	{
		if ( ! lastSearchHitPath )
			fNext = false ;
	}
	var fHit = false ;
	var regEx ;
	if ( fRegEx )
		regEx = new RegExp( target, "i" );
	else
		target = target.toLowerCase();
	var isVar = true ;
	var foundStartPath = ! fNext ;
	function _searchCallback ( a, prop, curDepth, path )
	{
		if ( fHit ) return 1 ;

		var fPos = -1 ;
		isVar = !( a[ prop ] && typeof( a[ prop ] ) == "object" );
		if ( !foundStartPath )
		{
			foundStartPath = ( path == lastSearchHitPath );
		}
		else
		{
			if ( searchType >= 0 )
			{
				if ( fRegEx )
					fPos = prop.toString().search( regEx );
				else
					fPos = prop.toString().toLowerCase().indexOf( target );
			}
			if ( isVar && (fPos == -1) && (searchType <= 0) )
			{
				if ( fRegEx )
					fPos = a[ prop ].toString().search( regEx );
				else
					fPos = a[ prop ].toString().toLowerCase().indexOf( target );
			}
		}
		if ( fPos != -1 )
		{
			lastSearchHitPath = path ;
			fHit = true ;
			return 1;
		}
	}
	_enumPropArray( regData, _searchCallback, 0, false, false, true );
	if ( ! fHit )
	{
		lastSearchHitPath = "" ;
	}
	return ;
}
function search ( target, searchType, fNext, fRegEx )
{
	searchData( target, searchType, fNext, fRegEx );
	if ( ! lastSearchHitPath )
	{
		var msg = "没有 " + (fNext ? "更多 " : "" ) + "元素被发现符合要求. '"+ target + "'" ;
		alert( msg );
		return false ;
	}
	else
	{
		// display the parent folder
		var folderID = pathMap[ lastSearchHitPath.leftProp( -1 ) ];
		TheTOCTree.si( folderID, lastSearchHitPath.rightProp( 1 ) );
		if ( ! isNav4 )
		{
			TheTOCTree.hiliteItem( lastSearchHitPath.rightProp( 1 ) );
		}
		return true ;
	}
}	// search
/*
	REGTree class methods
*/
function REGTree ( winTOC, winContent )
{
	this.base = TOCTree ;
	this.base( winTOC, winContent );
	this.m_curItem = "" ;
}
REGTree.prototype = new TOCTree ;
REGTree.tableTag = 
	'<TABLE width="600" ID="theTable" CELLSPACING="0" CELLPADDING="4"' + 
	( !isIE ? ' BORDER="0">' : ' RULES="GROUPS" BORDER="1" FRAME="void">' );
REGTree.tableHeaderRow = 
	'<THEAD><TR><TH WIDTH="200">Name</TH><TH WIDTH="300">Value</TH><TH WIDTH="100">Type</TH></TR></THEAD>' ;
REGTree.CAPTION_BGCOLOR = "#BBBBBB" ;
REGTree.EVEN_BGCOLOR = "white" ;
REGTree.ODD_BGCOLOR = "#CCCCCC" ;
REGTree.HILITE_BGCOLOR = "#00CCFF" ;
REGTree.prototype.si = function ( id, propToHilite )
{
	if ( ! this.m_bInitialized ) return ;
	if ( (!propToHilite) && (this.m_curFolderID == id) ) return ;
	var folder = getElem( "z" + id );
	if ( ! folder ) 
	{
		return ;
	}
	this.exposeFolder( folder );
	this.hiliteFolder( folder );
	this.m_curFolderID = id ;
	top.curPath( IDToPathMap[ id ] );
	//var displayPath = makeDisplayPath( top.curPath() );
	if ( ! isNav4 )
		top.document.title = top.curPath();
	var sRows = "" ;
	var rowCounter = 0 ;
	var hiliteRow = 0 ;
	function _callback ( a, prop, curDepth )
	{
		var bgColorAttr = ' BGCOLOR="' ;
		if ( (!isNav4) || (prop != propToHilite) )
		{
			bgColorAttr += ( (rowCounter % 2) ? REGTree.EVEN_BGCOLOR : REGTree.ODD_BGCOLOR ) + '"' ;
		}
		else
		{
			bgColorAttr += REGTree.HILITE_BGCOLOR + '"' ;
			hiliteRow = rowCounter ;
		}
		if ( a[ prop ] && typeof( a[ prop ] ) == "object" )
		{
			id++ ;
			if ( curDepth == 0 )
			{
				sRows += '<TR' + bgColorAttr + '><TD><A HREF="javascript://" onclick="TheTOCTree.si(' + id + ');">' + prop.toString().ent() + '</A></TD><TD>&nbsp;</TD><TD>List</TD></TR>' ;
			}
		}
		else if ( curDepth == 0 )
		{
			sRows += '<TR' + bgColorAttr + '><TD>' + prop.toString().ent() + '</TD><TD>' + a[ prop ].toString().ent() + 
				'</TD><TD>Variable</TD></TR>' ;
		}
		if ( curDepth == 0 ) rowCounter++ ;
		return 0;
	}
	_enumPropArray( linkMap[ id ], _callback, 0, true );
	var captionTag = ( !isNav4 ?
			'<CAPTION>contents of ' + top.curPath() + '</CAPTION>' : 
			'<TR BGCOLOR="' + REGTree.CAPTION_BGCOLOR + '"><TD colspan="3" align="left" valign="top">contents of ' + location + "/" + top.curPath() + "</TD></TR>" );
	var itemsHTML = 
			REGTree.tableTag + 
			captionTag + 
			REGTree.tableHeaderRow +
			sRows + 
			'</TABLE>' ;
	if ( ! isNav4 )
	{
		getElem( "DATA_DIV", top.DUMP.document ).innerHTML = itemsHTML ;
	}
	else	// Nav4
	{
		var doc = top.DUMP.document.layers[ 0 ].document ;
		doc.open();
		doc.write( itemsHTML );
		doc.close();
		//guesstimate new height of window 
		// 24 is the estimated row height, 3 accounts for the caption and header rows plus a buffer row
		top.DUMP.window.height = top.DUMP.document.height = ((rowCounter + 3) * 24);
		if ( hiliteRow )
		{

			top.DUMP.window.scroll( 0, ((hiliteRow + 3) * 24) );
		}
	}
	return false;
}	// si

REGTree.prototype.hiliteItem = function ( prop )
{
	// loop through the rows, skipping the header row
	var theTable = getElem( "theTable", top.frames.DUMP.document );
	for ( var i = 1; i < theTable.rows.length; i++ )
	{
		var row = theTable.rows[ i ];
		// prop will be the text of the first cell
		if ( this.m_curItem && this.m_curItem == prop )
		{
			row.style.backgroundColor = "" ;
		}
		if ( -1 != row.cells[ 0 ].innerHTML.indexOf( prop ) )
		{
			row.style.backgroundColor = REGTree.HILITE_BGCOLOR ;
			if ( ! isElemInView( row, top.frames.DUMP ) )
			{
				scrollVertToElem( row, top.frames.DUMP );
			}
			break ;
		}
	}
	this.m_curItem = prop ;
}	// hiliteItem


